package com.photoeditor.demo.model.mlkit;

import android.graphics.Bitmap;
import android.support.annotation.NonNull;

import com.common.base.utils.thread.ThreadPool;
import com.google.firebase.ml.vision.face.FirebaseVisionFace;
import com.photoeditor.demo.model.mlkit.facedetection.FaceContourDetectorProcessor;
import com.photoeditor.demo.model.mlkit.facedetection.FaceDetectionProcessor;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * Created by @author winn on 2018/12/19.
 */
public class ImageFaceDetector {

    public interface OnImageFaceDetectListener {
        void onDetectFaceSuccess(@NonNull List<FirebaseVisionFace> results);

        void onDetectFaceFailure(@NonNull Exception e);

        void onDetectFaceLandmarkSuccess(@NonNull List<FirebaseVisionFace> results);

        void onDetectFaceLandmarkFailure(@NonNull Exception e);
    }

    private WeakReference<OnImageFaceDetectListener> mListener;
    private FaceDetectionProcessor mFaceDetectionProcessor;
    private FaceContourDetectorProcessor mFaceContourDetectorProcessor;

    public ImageFaceDetector() {
        mFaceDetectionProcessor = new FaceDetectionProcessor();
        mFaceDetectionProcessor.setOnDetectFaceListener(new OnDetectFaceListener() {
            @Override
            public void onDetectFaceSuccess(@NonNull List<FirebaseVisionFace> results) {
                if (mListener != null && mListener.get() != null) {
                    mListener.get().onDetectFaceSuccess(results);
                }
            }

            @Override
            public void onDetectFaceFailure(@NonNull Exception e) {
                if (mListener != null && mListener.get() != null) {
                    mListener.get().onDetectFaceFailure(e);
                }
            }
        });
        mFaceContourDetectorProcessor = new FaceContourDetectorProcessor();
        mFaceContourDetectorProcessor.setOnDetectFaceListener(new OnDetectFaceListener() {
            @Override
            public void onDetectFaceSuccess(@NonNull List<FirebaseVisionFace> results) {
                if (mListener != null && mListener.get() != null) {
                    mListener.get().onDetectFaceLandmarkSuccess(results);
                }
            }

            @Override
            public void onDetectFaceFailure(@NonNull Exception e) {
                if (mListener != null && mListener.get() != null) {
                    mListener.get().onDetectFaceLandmarkFailure(e);
                }
            }
        });
    }

    public void release() {
        if (mFaceDetectionProcessor != null) {
            mFaceDetectionProcessor.stop();
        }
    }

    public void setListener(OnImageFaceDetectListener listener) {
        if (listener != null) {
            mListener = new WeakReference<>(listener);
        } else {
            if (mListener != null) {
                if (mListener.get() != null) mListener.clear();
                mListener = null;
            }
        }

    }

    /**
     * 识别图片中有几张脸
     * @param bitmap
     */
    public void startDetect(Bitmap bitmap) {
        detectFaceAsync(bitmap);
    }

    /**
     * 识别图片中的人脸坐标（图片中有多张人脸时，mlkit只能识别出一张人脸的关键点，外部需要对图片做裁剪）
     * @param bitmap
     */
    public void startDetectLandmark(Bitmap bitmap) {
        detectLandmarkAsync(bitmap);
    }

    private void detectFaceAsync(final Bitmap bitmap) {
        ThreadPool.getSubThreadHandler().post(new Runnable() {
            @Override
            public void run() {
                if (mFaceDetectionProcessor != null) {
                    mFaceDetectionProcessor.process(bitmap, null);
                }
            }
        });
    }

    private void detectLandmarkAsync(final Bitmap bitmap) {
        ThreadPool.getSubThreadHandler().post(new Runnable() {
            @Override
            public void run() {
                if (bitmap != null && !bitmap.isRecycled() && mFaceContourDetectorProcessor != null) {
                    mFaceContourDetectorProcessor.process(bitmap, null);
                }
            }
        });
    }
}
